package com.turing.post.capitalaccounts.impl;

import java.math.BigInteger;
import java.util.Date;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import com.turing.post.capitalaccounts.util.CapitalApplicationException;
import com.turing.post.capitalaccounts.util.CapitalRespCode;
import com.turing.post.capitalaccounts.util.SaleCapitalDetail;
import com.turing.post.capitalaccounts.util.SaleCapitalDetailDao;
import com.turing.post.capitalaccounts.util.SaleCreditDepositBill;
import com.turing.post.capitalaccounts.util.SaleCreditDepositBillBusiness;
import com.turing.post.capitalaccounts.util.SaleCreditDepositBillDao;
import com.turing.post.common.util.PCPSCommonDao;
import com.turing.post.common.util.SysOpUser;
import com.turing.post.common.util.SysOpUserDao;
import com.turing.post.common.util.SysOperLog;
import com.turing.post.common.util.SysOperLogDao;
import com.turing.post.organization.util.IssueCompany;
import com.turing.post.organization.util.IssueCompanyDao;
import com.turing.post.organization.util.SaleBranch;
import com.turing.post.organization.util.SaleBranchBusiness;
import com.turing.post.organization.util.SaleBranchDao;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSWebInput;

@Stateless(mappedName = "capitalaccounts.impl.SaleCreditDepositBillBusinessImpl")
@Remote
@Local
public class SaleCreditDepositBillBusinessImpl implements
		SaleCreditDepositBillBusiness {

	@EJB(mappedName = "capitalaccounts.impl.SaleCreditDepositBillDaoImpl")
	private SaleCreditDepositBillDao saleCreditDbImpl;

	@EJB(mappedName = "common.impl.PCPSCommonDaoImpl")
	private PCPSCommonDao pcpsCommonDaoImpl;

	@EJB(mappedName = "organization.impl.SaleBranchDaoImpl")
	private SaleBranchDao saleBranchDaoImpl;

	@EJB(mappedName = "common.impl.SysOperLogDaoImpl")
	private SysOperLogDao sysOperLogDaoImpl;
	@EJB(mappedName = "organization.impl.SaleBranchBusinessImpl")
	private SaleBranchBusiness saleBranchBusinessImpl;

	@EJB(mappedName = "organization.impl.IssueCompanyDaoImpl")
	private IssueCompanyDao issueCompanyDaoImpl;

	@EJB(mappedName = "capitalaccounts.impl.SaleCapitalDetailDaoImpl")
	private SaleCapitalDetailDao saleCapitalDetailDaoImpl;

	@EJB(mappedName = "common.impl.SysOpUserDaoImpl")
	private SysOpUserDao sysOpUserDaoImpl;

	@Override
	public void cancelSaleCreditDB(PCPSWebInput webInput,
			SaleCreditDepositBill obj) throws PCPSApplicationException {
		// 业务检查
		if (obj == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.RC_ARGS_NULL, "参数为NULL");
		}
		SaleCreditDepositBill oldObj = saleCreditDbImpl
				.getSaleCreditDepositBillById(obj.getSaleCreditDepositBillId());
		BigInteger amount = oldObj.getAmount();
		BigInteger oldId = oldObj.getSaleCreditDepositBillId();
		// 1.判断账单是否存在
		if (null == oldObj) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRCODE_CATEGORY_APPLICATION,
					CapitalRespCode.SaleCreditDepositBill_null, "不存在此账单!");
		}

		// 2.判断此账单是否已被撤销
		if (null != oldObj.getCancelSaleCreditDepositBillId()) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRCODE_CATEGORY_APPLICATION,
					CapitalRespCode.BILL_IS_CANCEL, "此账单已被撤销!");
		}

		// 2.判断此账单是否为当前操作员所录入的账单
		if (!oldObj.getOperId().equals(obj.getOperId())) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRCODE_CATEGORY_APPLICATION,
					CapitalRespCode.SaleCreditDepositBill_not_same_oper,
					"被撤单据应为同一操作员!");
		}

		// 3.检查发卡方（是否激活）
		IssueCompany issueCompany = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(oldObj.getIssueCompanyNo());
		if (null != issueCompany
				&& issueCompany.getActivate().equals(
						IssueCompany.ISSUECOMPANY_ACTIVATE_NOTACTIVATED)) {
			throw new CapitalApplicationException(
					CapitalRespCode.SYSBRANCH_NOT_STATUS, "发卡商机构未激活!");
		}
		// 4.检查发卡方（是否处于日终状态）
		if (null != issueCompany
				&& issueCompany.getStatus().equals(
						IssueCompany.ISSUECOMPANY_NORMAL_ENDDAY)) {
			throw new CapitalApplicationException(
					CapitalRespCode.SaleCreditDepositBill_STAUTS_TRUE,
					"发卡商机构正在日终!");
		}
		// 5.判断SaleBranch.Credit >= SaleBranch.CreditLowLimit
		SaleBranch saleBranch = saleBranchDaoImpl
				.getSaleBranchBySaleBranchNo(oldObj.getSaleBranchNo());
		saleBranch.setCredit(saleBranch.getCredit()
				.subtract(oldObj.getAmount()));
		if (saleBranch.getCredit().compareTo(saleBranch.getCreditLowLimit()) < 0) {
			throw new CapitalApplicationException(
					CapitalRespCode.SaleCreditDepositBill_Credit_LOWLIMIT,
					"信用额度" + saleBranch.getCredit() + " < 预存款下限"
							+ saleBranch.getCreditLowLimit());
		}

		// PCPSWebInput webInput = new PCPSWebInput();
		// webInput.setOperId(obj.getOperId());
		// webInput.setOperBranchNo(oldObj.getSaleBranchNo());
		// 6.实时更新SaleBranch.Credit += -原缴款单金额
		saleBranchBusinessImpl.updateSaleBranchInfo(webInput, saleBranch);

		// 取当前时间
		Date curTime = pcpsCommonDaoImpl.getDatabaseSysTime();

		// 7.插入撤销账单
		SaleCreditDepositBill newObj = new SaleCreditDepositBill();
		BigInteger newSaleCreditDepositBillId = pcpsCommonDaoImpl
				.getUniqueIntegerKey();
		newObj.setSaleCreditDepositBillId(newSaleCreditDepositBillId);
		newObj.setIssueCompanyNo(oldObj.getIssueCompanyNo());
		newObj.setSaleBranchNo(oldObj.getSaleBranchNo());
		newObj.setTranDate(issueCompany.getTranDate());
		newObj.setTranTime(curTime);
		newObj.setAmount(BigInteger.valueOf(0).subtract(oldObj.getAmount()));
		newObj.setDepositType(oldObj.getDepositType());
		newObj.setIssueBankAccountId(oldObj.getIssueBankAccountId());
		newObj.setPaidBankAccountId(oldObj.getPaidBankAccountId());
		newObj.setVoucherNo(oldObj.getVoucherNo());
		newObj.setVoucherImageId(oldObj.getVoucherImageId());
		newObj.setVoucherRemark(oldObj.getVoucherRemark());
		newObj.setCancelSaleCreditDepositBillId(oldId);
		newObj.setOperId(oldObj.getOperId());
		newObj.setRemark(oldObj.getRemark());

		saleCreditDbImpl.insertSaleCreditDepositBill(newObj);

		// 8.根据CancelSaleCreditDepositBillId获取刚才插入的信息,
		oldObj.setSaleCreditDepositBillId(oldId);
		oldObj.setCancelSaleCreditDepositBillId(newSaleCreditDepositBillId);
		oldObj.setAmount(amount);
		saleCreditDbImpl.updateSaleCreditDepositBill(oldObj);

		// 插入销售机构资金明细
		SaleCapitalDetail saleCapitalDetail = new SaleCapitalDetail();
		saleCapitalDetail.setSaleBranchNo(oldObj.getSaleBranchNo());
		saleCapitalDetail.setTranDate(issueCompany.getTranDate());
		saleCapitalDetail.setTranTime(curTime);
		saleCapitalDetail.setTranType(SaleCapitalDetail.TRANTYPE_CANCELDEPOSIT);
		saleCapitalDetail.setTicketId(newSaleCreditDepositBillId);
		saleCapitalDetail.setCreditDeposit(BigInteger.valueOf(0).subtract(
				amount));
		saleCapitalDetail.setOperId(oldObj.getOperId());
		saleCapitalDetail.setRemark(oldObj.getRemark());
		saleCapitalDetailDaoImpl.insertSaleCapitalDetail(saleCapitalDetail);

		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Add, "撤销销售机构上存/缴现金支出单", "SaleBranchNo:"
						+ saleCapitalDetail.getSaleBranchNo());
	}

	@Override
	public void insertSaleCreditDepositBill(PCPSWebInput webInput,
			SaleCreditDepositBill obj) throws PCPSApplicationException {
		// 业务检查
		if (obj == null || webInput == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.RC_ARGS_NULL, "参数为NULL");
		}

		SysOpUser sysOpUser = sysOpUserDaoImpl.getSysOpUserByOperId(webInput
				.getOperId());
		// 判断操作员是否存在
		if (sysOpUser == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.OPER_NULL, "操作员为NULL");
		}
		IssueCompany issueCompany = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(sysOpUser.getOperBranchNo());
		// 判断发卡商是否为激活状态
		if (issueCompany == null) {
			throw new CapitalApplicationException(
					CapitalRespCode.ISSUECOMPANY_NULL, "操作员不为发卡商");
		}
		// 判断发卡商是否为激活状态
		if (issueCompany.getActivate().equals(
				IssueCompany.ISSUECOMPANY_ACTIVATE_NOTACTIVATED)) {
			throw new CapitalApplicationException(
					CapitalRespCode.SYSBRANCH_NOT_STATUS, "发卡商未激活");
		}
		// 判断是否为日终(交易)状态
		if (issueCompany.getStatus().equals(
				IssueCompany.ISSUECOMPANY_NORMAL_ENDDAY)) {
			throw new CapitalApplicationException(
					CapitalRespCode.NORMAL_ENDDAY, "发卡商为正在日终状态");
		}
		SaleBranch saleBranch = saleBranchDaoImpl.getSaleBranchForUpdate(obj
				.getSaleBranchNo());
		// 判断销售机构是否存在
		if (saleBranch == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.SALEBRANCH_NULL, "销售机构为NULL");
		}

		// SaleCompany saleCompany=
		// saleCompanyDaoImpl.getSaleCompanyBySaleCompanyNo(saleBranch);
		// 判断销售商是否为激活状态
		if (saleBranch.getStatus().equals(
				SaleBranch.SALEBRANCH_STATUS_NOTACTIVATED)) {
			throw new CapitalApplicationException(
					CapitalRespCode.SYSBRANCH_NOT_STATUS, "销售商未激活");
		}

		// 销售机构是否属于操作员的管辖机构
		// if(!issueCompany.getIssueCompanyNo().equals(saleCompany.getIssueCompanyNo())){
		// throw new
		// CapitalApplicationException(CapitalRespCode.SALEBRANCH_NOTBELONG_SYSOPUSER,
		// "销售机构不属于操作员的管辖机构");
		// }

		// 销售机构是否属于操作员的管辖机构
		if (obj.getAmount().compareTo(BigInteger.valueOf(0)) <= 0) {
			throw new CapitalApplicationException(CapitalRespCode.AMOUNT_SMALL,
					"缴款金额<=0");
		}

		saleBranch.setCredit(saleBranch.getCredit().add(obj.getAmount()));
		// 信用额度与预存款下限比较
		if (saleBranch.getCredit().compareTo(saleBranch.getCreditLowLimit()) < 0) {
			throw new CapitalApplicationException(
					CapitalRespCode.SaleCreditDepositBill_Credit_LOWLIMIT,
					"信用额度SaleBranch.Credit < 预存款下限SaleBranch.CreditLowLimit");
		}

		// 实时更新SaleBranch.Credit += 原缴款单金额
		saleBranchDaoImpl.updateSaleBranch(saleBranch);

		// 取当前时间
		Date curTime = pcpsCommonDaoImpl.getDatabaseSysTime();

		// 机构上缴款录入
		BigInteger saleCreditDepositBillId = pcpsCommonDaoImpl
				.getUniqueIntegerKey();
		obj.setSaleCreditDepositBillId(saleCreditDepositBillId);
		obj.setIssueCompanyNo(issueCompany.getIssueCompanyNo());
		obj.setTranDate(issueCompany.getTranDate());
		obj.setTranTime(curTime);
		obj.setOperId(webInput.getOperId());
		saleCreditDbImpl.insertSaleCreditDepositBill(obj);

		// 插入销售机构资金明细
		SaleCapitalDetail saleCapitalDetail = new SaleCapitalDetail();
		saleCapitalDetail.setSaleBranchNo(obj.getSaleBranchNo());
		saleCapitalDetail.setTranDate(issueCompany.getTranDate());
		saleCapitalDetail.setTranTime(curTime);
		saleCapitalDetail.setTranType(SaleCapitalDetail.TRANTYPE_DEPOSIT);
		saleCapitalDetail.setTicketId(saleCreditDepositBillId);
		saleCapitalDetail.setCreditDeposit(obj.getAmount());
		saleCapitalDetail.setOperId(obj.getOperId());
		saleCapitalDetail.setRemark(obj.getRemark());
		saleCapitalDetailDaoImpl.insertSaleCapitalDetail(saleCapitalDetail);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Add, "插入缴款入帐单", "SaleBranchNo:"
						+ saleCapitalDetail.getSaleBranchNo());
	}

	@Override
	public void updateSaleCreditDepositBill(PCPSWebInput webInput,
			SaleCreditDepositBill obj) throws PCPSApplicationException {
		if (webInput.getOperId() == null) {
			return;
		}
		if (obj.getVoucherImageId() == null) {
			return;
		}
		SaleCreditDepositBill scdb = saleCreditDbImpl
				.getSaleCreditDepositBillByIdForUpdate(obj
						.getSaleCreditDepositBillId());
		if (scdb != null) {
			scdb.setVoucherImageId(obj.getVoucherImageId());
			saleCreditDbImpl.updateSaleCreditDepositBill(scdb);
			// 日志记录
			sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
					SysOperLog.operType_Edit, "修改缴款入帐单凭证图片", "SaleBranchNo:"
							+ scdb.getSaleBranchNo());
		}
	}
}
